package controller;

import java.util.List;

import javax.xml.xpath.XPathExpressionException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import utilities.AssertionAnalyser;
import utilities.DocumentUtilities;
import utilities.Writer;
import utilities.XmlUtilities;

public class OperationsController {
	private static final Logger LOG = LoggerFactory
			.getLogger(OperationsController.class);
	public static Writer writer = new Writer();

	/**
	 * This method gets the file, the testname of the node to be changed, the
	 * xml piece to replace the node with and replaces the node and returns an
	 * output file with the replaced node
	 * 
	 * @param 
	 * @return
	 */
	public static boolean changeJmeterNode(String outputFile, String fileName,
			String xmlPiece, String testName, boolean fromFile) {
		Document doc = DocumentUtilities.buildDoc(fileName);
		Document doclet = DocumentUtilities.buildDoclet(xmlPiece);

		Node nodeToToss = XmlUtilities.findNode(testName, doc);
		XmlUtilities.changeNode(nodeToToss, doc, doclet);
		Writer.writer(doc, outputFile, fromFile);
		return true;

	}

	/**
	 * This method gets the file, the testname of the node, the xml piece and
	 * the testname of the specific node to be swapped and then returns an
	 * output file with the swapped node
	 * 
	 * @param po
	 * @return
	 */

	public static boolean swapJmeterNode(String outputFile, String fileName,
			String xmlPiece, String xmlTestName, String testName, boolean fromFile) {
		Document doc = DocumentUtilities.buildDoc(fileName);
		Document doclet = DocumentUtilities.buildDoc(xmlPiece);
		Node nodeToToss = XmlUtilities.findNode(testName, doc);
		Node nodeToInsert = XmlUtilities.findNode(xmlTestName, doclet);

		XmlUtilities.swapNode(nodeToToss, doc, nodeToInsert, doclet);
		if ((null!= doc) && (null!= doclet)
				&& (null!= nodeToToss) && (null != nodeToInsert)) {
			// write the file to output
			Writer.writer(doc, outputFile, fromFile);
		} else {
			LOG.error("** JMeter Node not swapped  **");
		}
		return true;

	}

	/**
	 * This method gets the file, the testname of the node, the attribute to be
	 * changed and the user input and returns an output file with the changed
	 * attribute of the node.
	 * 
	 * @param po
	 * @return
	 */
	public static boolean changeJmeterAttribute(String outputFile,
			String fileName, String testName, String attribute, String userInput, boolean fromFile) {
		// DocumentUtilities.createOutputFile(outputFile);
		Document doc = DocumentUtilities.buildDoc(fileName);
		Node nodeToAlter = XmlUtilities.findNode(testName, doc);
		XmlUtilities.changeAttribute(nodeToAlter, doc, attribute, userInput);

		// write the file to output
		Writer.writer(doc, outputFile, fromFile);
		return true;
	}

	/**
	 * This method gets the file and breaks the multiple patterns to individual
	 * assertions and returns the output file
	 * 
	 * @param po
	 * @return
	 */
	public static boolean analyzeJmeterAssertion(String fileName,
			String outputFile, boolean fromFile) {
		List<Element> list;
		boolean complete = true;
		Document doc = DocumentUtilities.buildDoc(fileName);
		if(!fromFile){
			AssertionAnalysisController alterA = new AssertionAnalysisController();
			try {
				alterA.printAssertions(doc);
			} catch (XPathExpressionException e1) {
				LOG.error("****XPathExpressionException-1*****");
				complete = false;
			}
			list = alterA.nodesToAlter(doc);
		}else {
			list = AssertionAnalyser.findMultipleAssertionPatterns(doc);
		}
		for (int a = 0; a < list.size(); a++) {
			try {
				AssertionAnalyser.breakMultipelPatternsIntoAssertions(
						list.get(a), doc);

			} catch (XPathExpressionException e) {
				complete = false;
				LOG.error("****XPathExpressionException-2*****");
			}
		}
		Writer.writer(doc, outputFile, fromFile);
		return complete;
	}

	/**
	 * getter and setter for scan for testing
	 * 
	 * @return
	 */
	public static Writer getWriter() {
		return writer;
	}

	public void setWriter(Writer writer) {
		OperationsController.writer = writer;
	}
}
